/*
*		TCP¿Í»§¶ËÓÃsocketÒÔÁ¬½ÓÔ¶³Ì·þÎñÆ÷,DataRev°ü
*/

#pragma once

#include <boost/asio.hpp>
#include <boost/signals2.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
#include "CxType.h"
#include "CxPort.h"


//¿ªÊ¼ÃüÃû¿Õ¼ä
BEGIN_NAMESPACE(DataRevPart)



class	CxTcpClient		: public CxPort
{


	typedef boost::asio::ip::tcp::socket		_Socket;
	typedef boost::asio::ip::address			_Addr;
	typedef boost::asio::ip::tcp::endpoint		_EndPoint;
	typedef boost::asio::io_service				_IoService;
	typedef boost::thread						_Thread;

public:
	typedef	boost::function<void(bool)>					_ConnectFunc;
	typedef boost::signals2::signal<void(bool)>			_ConnectSig;

	typedef boost::signals2::signal<void()>				_BreakSig;
	typedef boost::function<void()>						_BreakFunc;

public:
	//Ö÷Òª¹¹Ôìº¯Êý
	CxTcpClient(const  string  &,UINT ,
				_ConnectFunc _func=__EmptyFunc);
	CxTcpClient();

	~CxTcpClient();
public:

	//Tcp²Ù×÷º¯Êý
	bool		OpenPort(const	string &,UINT	portno,
						_ConnectFunc _func=__EmptyFunc);

	bool		ClosePort();
	//Tcp×´Ì¬º¯Êý
	bool		IsOpen()const;
	UINT		GetPortState()const;

	//»ù±¾¶ÁÐ´²Ù×÷
	size_t		ReadPort(	BYTE	*,size_t );
	size_t		WritePort(	const BYTE *,size_t );

	//»ù±¾Òì²½¶ÁÐ´²Ù×÷
	void		Async_ReadPort(		BYTE* ,size_t ,Async_Handler&);
	void		Async_WritePort(const  BYTE *,size_t,Async_Handler &);


public:
	//Ìí¼ÓÁ¬½Ó³É¹¦»Øµ÷º¯Êý
	void		AddConnectedFunc(_ConnectFunc _func)
	{
		sig_connect.connect(1,boost::bind(_func,_1));
	}
	void		AddBreakFunc(_BreakFunc	_func)
	{
		sig_break.connect(boost::bind(_func));
	}
private:

	int				m_portno;
	_Socket			m_socket;
	_Addr			m_addr;
private:

	//Á¬½ÓÐÅºÅ
	_ConnectSig		sig_connect;
	//ÖÐ¶ÏÐÅºÅ
	_BreakSig		sig_break;
	
private:
	//Á¬½Ó³É¹¦´¦Àíº¯Êý
	void			ConnectedFunc(const ERRCODE &e);
	//´íÎó´¦Àíº¯Êý
	void			HandleErrcode(const ERRCODE &e);

public:

    static	bool                                s_isioinit;

    static  size_t                              s_ioref;
	//È«¾ÖÎ¨Ò»io_service
    static	 _IoService                         s_ioservice;
	//È«¾ÖÎ¨Ò»IOÍê³É¶Ë¿ÚÏß³Ì
    static  boost::thread_group                 s_iothread;
	//È«¾ÖÎ¨Ò»IO¿ª¹Ø±äÁ¿   

    typedef boost::shared_ptr<boost::asio::io_service::work> iowork;

    static  std::vector<iowork>                 s_workgroup;

private:
	//È«¾ÖIOÔËÐÐÏß³Ìº¯Êý
    static	void		IoRunFunc();

    void				_RunIo();
    void                _ReleaseIO();
};

//½áÊøÃüÃû¿Õ¼ä
END_NAMESPACE 
